#include "pch.h"
#include "TextLayout.h"
#include "Helper.h"
#include "ErrorCodes.h"
#include "Factories.h"
#include "TextFormat.h"
#include "Typography.h"

using namespace Platform;
using namespace Microsoft::WRL;

using namespace DXBase;
using namespace DXBase::DWrite;


TextLayout::TextLayout(Platform::String^ string, TextFormat^ format, float maxWidth, float maxHeight)
{
	if (!string || !format)
		throw ref new NullReferenceException();
	HR2Ex(Factories::GetDWriteFactory()->CreateTextLayout(
		string->Data(),
		string->Length(),
		format->GetNativeFormat().Get(),
		maxWidth,
		maxHeight,
		mTextLayout.GetAddressOf()
		));
}

void TextLayout::SetFontSize(float value, Range range)
{
	mTextLayout->SetFontSize(value, makeDWrite(range));
}
bool TextLayout::TryGetFontSize(uint32 pos, float* value, Range* range)
{
	if (!value)
		return false;
	DWRITE_TEXT_RANGE drange;
	if (FAILED(mTextLayout->GetFontSize(pos, value, &drange)))
		return false;
	if (range)
		*range = fromDWrite(drange);
	return true;
}

void TextLayout::SetTypography(Typography^ value, Range range)
{
	mTextLayout->SetTypography(value->pTypo.Get(), makeDWrite(range));
}
bool TextLayout::TryGetTypography(uint32 pos, Typography^* value, Range* range)
{
	if (!value)
		return false;
	DWRITE_TEXT_RANGE drange;
	ComPtr<IDWriteTypography> typo;
	if (FAILED(mTextLayout->GetTypography(pos, typo.GetAddressOf(), &drange)))
		return false;
	*value = ref new Typography(typo);
	if (range)
		*range = fromDWrite(drange);
	return true;
}

void TextLayout::SetFontWeight(FONT_WEIGHT value, Range range)
{
	mTextLayout->SetFontWeight(makeD2D(value), makeDWrite(range));
}
bool TextLayout::TryGetFontWeight(uint32 pos, FONT_WEIGHT* value, Range* range)
{
	if (!value)
		return false;
	DWRITE_TEXT_RANGE drange;
	DWRITE_FONT_WEIGHT dvalue;
	if (FAILED(mTextLayout->GetFontWeight(pos, &dvalue, &drange)))
		return false;
	*value = fromD2D(dvalue);
	if (range)
		*range = fromDWrite(drange);
	return true;
}

void TextLayout::SetFontStyle(FONT_STYLE value, Range range)
{
	mTextLayout->SetFontStyle(makeD2D(value), makeDWrite(range));
}
bool TextLayout::TryGetFontStyle(uint32 pos, FONT_STYLE* value, Range* range)
{
	if (!value)
		return false;
	DWRITE_TEXT_RANGE drange;
	DWRITE_FONT_STYLE dvalue;
	if (FAILED(mTextLayout->GetFontStyle(pos, &dvalue, &drange)))
		return false;
	*value = fromD2D(dvalue);
	if (range)
		*range = fromDWrite(drange);
	return true;
}

void TextLayout::SetFontStretch(FONT_STRETCH value, Range range)
{
	mTextLayout->SetFontStretch(makeD2D(value), makeDWrite(range));
}
bool TextLayout::TryGetFontStretch(uint32 pos, FONT_STRETCH* value, Range* range)
{
	if (!value)
		return false;
	DWRITE_TEXT_RANGE drange;
	DWRITE_FONT_STRETCH dvalue;
	if (FAILED(mTextLayout->GetFontStretch(pos, &dvalue, &drange)))
		return false;
	*value = fromD2D(dvalue);
	if (range)
		*range = fromDWrite(drange);
	return true;
}

void TextLayout::SetUnderline(bool value, Range range)
{
	mTextLayout->SetUnderline(value, makeDWrite(range));
}
bool TextLayout::TryGetUnderline(uint32 pos, bool* value, Range* range)
{
	if (!value)
		return false;
	DWRITE_TEXT_RANGE drange;
	BOOL dvalue;
	if (FAILED(mTextLayout->GetUnderline(pos, &dvalue, &drange)))
		return false;
	*value = dvalue != FALSE;
	if (range)
		*range = fromDWrite(drange);
	return true;
}

void TextLayout::SetStrikethrough(bool value, Range range)
{
	mTextLayout->SetStrikethrough(value, makeDWrite(range));
}
bool TextLayout::TryGetStrikethrough(uint32 pos, bool* value, Range* range)
{
	if (!value)
		return false;
	DWRITE_TEXT_RANGE drange;
	BOOL dvalue;
	if (FAILED(mTextLayout->GetStrikethrough(pos, &dvalue, &drange)))
		return false;
	*value = dvalue != FALSE;
	if (range)
		*range = fromDWrite(drange);
	return true;
}
